Personal Site
1---
2import { getCollection } from "astro:content";
3import Base from "/components/Base.astro";
4import { render } from "astro:content";
5
6import Box4x3Mask from "/assets/box-4x3-mask.png";
7import Hr from "/assets/hr.png";
8
9import "/components/markdown.css";
10
11export async function getStaticPaths() {
12 return await Promise.all(
13 await getCollection("blog").then((posts) =>
14 posts.map(async (post) => ({
15 params: { slug: post.id },
16 props: {
17 post,
18 banner: await import(
19 `../../content/blog/assets/${post.data.banner.replace(".png", "")}.png`
20 ).then(({ default: img }) => img.src as string),
21 },
22 })),
23 ),
24 );
25}
26
27const { post, banner } = Astro.props;
28const { Content } = await render(post);
29---
30
31<Base
32 title={post.data.title}
33 graph={{
34 description: post.data.bio,
35 url: Astro.url.toString(),
36 type: "article",
37 image: banner,
38 }}
39>
40 <article>
41 <header
42 style={`
43 --box-4x3-mask-png: url(${Box4x3Mask.src});
44 `}
45 >
46 <img src={banner} alt="" />
47 <div class="header">
48 <h1>{post.data.title}</h1>
49 <p>{post.data.bio}</p>
50 <time
51 datetime={`${post.data.pub.getFullYear()}-${post.data.pub.getMonth() + 1}-${post.data.pub.getDate()}`}
52 >
53 {post.data.pub.getDate()}-{post.data.pub.getMonth() + 1}-{
54 post.data.pub.getFullYear()
55 }
56 </time>
57 </div>
58 </header>
59
60 <hr style={`--hr-png: url(${Hr.src});`} />
61
62 <div class="markdown-style">
63 <Content />
64 </div>
65 </article>
66</Base>
67
68<style>
69 header {
70 max-width: 60ch;
71 padding: 10px;
72 margin: auto;
73
74 position: relative;
75 }
76
77 .header {
78 /* just use old layout on mobile
79 it works there */
80 @media not (max-width: 60ch) {
81 position: absolute;
82 inset: auto 50px 0;
83
84 background-image: var(--box-4x3-mask-png);
85 background-size: 100% 100%;
86 padding: 20px;
87 }
88 }
89
90 img {
91 width: 100%;
92 aspect-ratio: 4/3;
93 object-fit: cover;
94 mask-image: var(--box-4x3-mask-png);
95 mask-size: 100%;
96 }
97
98 time {
99 color: #000000b0;
100 }
101
102 hr {
103 margin-block: 5px;
104 height: 5px;
105 border: none;
106 border-image: var(--hr-png) 0 5 fill / 0 5px round;
107 width: 100%;
108 max-width: 70ch;
109 margin-inline: auto;
110 }
111</style>